package com.caigou.component;


import cn.hutool.core.lang.Dict;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import com.caigou.bean.cms.entity.Template;
import com.caigou.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;


/**
 * 模板处理组件
 */
@Component
@Slf4j
public class TemplateComponent {

    @Resource
    private TemplateService templateService;

    @Value("${webRoot}")
    private String webRoot;
    @Value("${webRoot2}")
    private String webRoot2;

    @Value("${domain}")
    private String domain;

    @Value("${domain2}")
    private String domain2;

    /**
     * 生成静态文件(碎片状态可控)
     * @param templateCode  模板编号(最外层)
     * @param templateData  模板中需要的变量(嵌套的碎片与展示字段)
     * @return
     */
    public String createHtml(String templateCode, Map<String,Object> templateData) throws IOException{
        Template template  = templateService.selectByTemplateCode(templateCode);// 根据模板编号获取对应的模板配置
        log.info("templateCode={}, template={}", templateCode, template);
        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));// 配置模板存放静态资源路径
        cn.hutool.extra.template.Template contentTemplate = engine.getTemplate(template.getTemplateFile());// 根据数据库配置获取对应的模板文件
        Dict contentDict = Dict.create();// 填充对应的模板变量
        for (Map.Entry<String, Object> entry : templateData.entrySet()) {
            contentDict.set(entry.getKey(), entry.getValue());
        }
        long start0 = System.currentTimeMillis();
        String content = contentTemplate.render(contentDict);// 生成静态文件结果代码
        long end0 = System.currentTimeMillis();
        log.debug("生成的静态内容是："+content);
        log.info("生成的静态内容耗时={}ms", (end0-start0));
        String extension = template.getTemplateType()==1 ? ".html" : ".htm";// 进行生成文件后缀的判别(如果当前模板为页面类型--生成的文件后缀为html、如果为碎片类型--生成的文件后缀为htm)
        File folder;// 生成文件的存放位置判别(是否需要散列文件夹)
        // 散列文件夹日期值
        Date date = null;
        if (null != templateData.get("createTime")){
            date = (Date)templateData.get("createTime");
        }
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy");
        SimpleDateFormat sdf2 = new SimpleDateFormat("MM");
        SimpleDateFormat sdf3 = new SimpleDateFormat("dd");




        // 判断生成静态资源存放文件夹（增加年份散列）
        String hashUrl1 = "";
        String hashUrl2 = "";
        String hashUrl3 = "";
        if (template.getTemplateIsHash() == 1){
            // 当前文件生成需要进行散列(散列规则待定)
            hashUrl1 = sdf1.format(date);
            hashUrl2 = sdf2.format(date);
            hashUrl3 = sdf3.format(date);
            // 判定文件夹是否存在
            folder = new File(webRoot+template.getUrlPath()+hashUrl1+"/"+hashUrl2+"/"+hashUrl3+"/");
        } else {
            //生成的文件不需要散列
            folder = new File(webRoot+template.getUrlPath());
        }
        if (!folder.exists()) folder.mkdirs();// 如果当前文件夹不存在--创建新的文件夹
        // 判断生成静态资源文件
        File file;// 生成文件判别
        if(template.getUrlFile() != null && template.getUrlFile().trim().length()>0){
            // 当前文件名称使用数据库配置的文件名称进行生成
            file = new File(folder,template.getUrlFile()+extension);
        }else{
            // 当前文件名称使用外部传参数据ID进行生成
            Object object = templateData.get("id");
            if(object!=null) {
                file = new File(folder, templateData.get("id") + extension); // 指配文件生成路径
            }else{//推荐作者碎片的id
                file = new File(folder, templateData.get("articlePromoterId") + extension); // 指配文件生成路径
            }
        }
        // 进行静态文件编写生成(输出文件流)
        long start = System.currentTimeMillis();
        Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
        writer.write(content);
        writer.flush();
        writer.close();
        long end = System.currentTimeMillis();
        String url;
        if (null != templateData.get("empireId") && !templateData.get("empireId").toString().equals("0")){
            // 帝国同步过来的数据
            url = template.getTemplateIsHash() == 1 ? domain2+template.getUrlPath()+hashUrl1+"/"+hashUrl2+"/"+hashUrl3+"/"+file.getName() : domain2+template.getUrlPath()+file.getName();
        } else {
            // 本站数据
            url = template.getTemplateIsHash() == 1 ? domain+template.getUrlPath()+hashUrl1+"/"+hashUrl2+"/"+hashUrl3+"/"+file.getName() : domain+template.getUrlPath()+file.getName();
        }
        log.info("该内容对应的url={},生成文件耗时={}ms", url, (end-start));
        return url;
    }

    // 二级域名底层页生成方法
    public String createHtml2(String templateCode, Map<String,Object> templateData) throws IOException{
        log.info("templateData ={}", templateData.get("hibuick"));
        log.info("articleId ={}", templateData.get("id"));
        Template template  = templateService.selectByTemplateCode(templateCode);// 根据模板编号获取对应的模板配置
        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));// 配置模板存放静态资源路径
        cn.hutool.extra.template.Template contentTemplate = engine.getTemplate(template.getTemplateFile());// 根据数据库配置获取对应的模板文件
        Dict contentDict = Dict.create();// 填充对应的模板变量
        for (Map.Entry<String, Object> entry : templateData.entrySet()) {
            contentDict.set(entry.getKey(), entry.getValue());
        }
        String content = contentTemplate.render(contentDict);// 生成静态文件结果代码
        String extension = template.getTemplateType()==1 ? ".html" : ".htm";// 进行生成文件后缀的判别(如果当前模板为页面类型--生成的文件后缀为html、如果为碎片类型--生成的文件后缀为htm)
        File folder;// 生成文件的存放位置判别(是否需要散列文件夹)
        // 散列文件夹日期值
        Date date = null;
        if (null != templateData.get("createTime")){
            date = (Date)templateData.get("createTime");
        }
        String chanelSite = (String) templateData.get("channelSite");
        String chanelSiteUrl = (String) templateData.get("channelSiteUrl");
        if (null == chanelSite || chanelSite.equals("") || null == chanelSiteUrl || chanelSiteUrl.equals("")){
            chanelSite = webRoot;
            chanelSiteUrl = domain;
        }
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
        // 文件散列规则(/caigou-web/web/20201111/XXXX.html)
        folder = new File(chanelSite+template.getUrlPath()+sdf1.format(date)+"/");
        log.info("文件夹目录为："+chanelSite+template.getUrlPath()+sdf1.format(date)+"/");
        log.info("文件夹是否存在："+folder.exists());
        if (!folder.exists()) folder.mkdirs();// 如果当前文件夹不存在--创建新的文件夹
        log.info("文件夹是否生成成功："+folder.exists());
        // 判断生成静态资源文件
        File file = new File(folder, templateData.get("id") + extension); // 指配文件生成路径
        log.info("静态文件生成结果为："+file.exists());
        // 进行静态文件编写生成(输出文件流)
        Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
        writer.write(content);
        writer.flush();
        writer.close();
        return chanelSiteUrl+template.getUrlPath()+sdf1.format(date)+"/"+templateData.get("id") + extension;
    }

    // 二级域名各频道首页生成方法
    public String createHtml3(String templateCode, Map<String,Object> templateData) throws IOException{
        Template template  = templateService.selectByTemplateCode(templateCode);// 根据模板编号获取对应的模板配置
        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));// 配置模板存放静态资源路径
        cn.hutool.extra.template.Template contentTemplate = engine.getTemplate(template.getTemplateFile());// 根据数据库配置获取对应的模板文件
        Dict contentDict = Dict.create();// 填充对应的模板变量
        for (Map.Entry<String, Object> entry : templateData.entrySet()) {
            contentDict.set(entry.getKey(), entry.getValue());
        }
        String content = contentTemplate.render(contentDict);// 生成静态文件结果代码
        String extension = template.getTemplateType()==1 ? ".html" : ".htm";// 进行生成文件后缀的判别(如果当前模板为页面类型--生成的文件后缀为html、如果为碎片类型--生成的文件后缀为htm)
        File folder;// 生成文件的存放位置判别(是否需要散列文件夹)
        String chanelSite = (String) templateData.get("channelSite");
        String chanelSiteUrl = (String) templateData.get("channelSiteUrl");
        if (null == chanelSite || chanelSite.equals("") || null == chanelSiteUrl || chanelSiteUrl.equals("")){
            chanelSite = webRoot;
            chanelSiteUrl = domain;
        }
        folder = new File(chanelSite+"/"+template.getUrlPath());
        if (!folder.exists()) folder.mkdirs();// 如果当前文件夹不存在--创建新的文件夹
        // 判断生成静态资源文件
        File file = new File(folder, template.getUrlFile() + extension); // 指配文件生成路径
        // 进行静态文件编写生成(输出文件流)
        Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
        writer.write(content);
        writer.flush();
        writer.close();
        return chanelSiteUrl+template.getUrlPath()+template.getUrlFile()+extension;
    }

    // 二级域名各频道列表页生成方法









    /**
     * 获取预览数据(不生成静态页)
     * @param templateCode 模板编号
     * @param templateData 模板中需要的变量(嵌套的碎片与展示字段)
     * @return html字符串
     */
    public String buildHtml(String templateCode, Map<String, Object> templateData){
        Template template  = templateService.selectByTemplateCode(templateCode);// 根据模板编号获取对应的模板配置
        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));// 配置模板存放静态资源路径
        cn.hutool.extra.template.Template contentTemplate = engine.getTemplate(template.getTemplateFile());// 根据数据库配置获取对应的模板文件
        Dict contentDict = Dict.create();// 填充对应的模板变量
        for (Map.Entry<String, Object> entry : templateData.entrySet()) {
            contentDict.set(entry.getKey(), entry.getValue());
        }
        String content = contentTemplate.render(contentDict);// 生成静态文件结果代码
        log.debug("生成的静态内容是："+content);
        return content;
    }

    public String test(String template, Map<String, Object> templateData){
        TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));// 配置模板存放静态资源路径
        cn.hutool.extra.template.Template contentTemplate = engine.getTemplate(template);// 根据数据库配置获取对应的模板文件
        Dict contentDict = Dict.create();// 填充对应的模板变量
        for (Map.Entry<String, Object> entry : templateData.entrySet()) {
            contentDict.set(entry.getKey(), entry.getValue());
        }
        String content = contentTemplate.render(contentDict);// 生成静态文件结果代码
        log.info("生成的静态内容是："+content);
        return content;
    }
}
